#include <iostream>
#include "tinyfsm.hpp"

// -----------------------
// 定义事件（控制指令）
// -----------------------

struct StartMoving : tinyfsm::Event {};
struct StopMoving : tinyfsm::Event {};
struct StartWorking : tinyfsm::Event {};
struct StopWorking : tinyfsm::Event {};

// 前向声明所有状态类
struct Idle;
struct Moving;
struct Working;

// -----------------------
// FSM 状态基类
// -----------------------

struct RobotState : tinyfsm::Fsm<RobotState>
{
    virtual void entry() {} // 状态进入动作
    virtual void exit() {}  // 状态退出动作

    // 默认事件处理（可被各状态继承重写）
    virtual void react(StartMoving const &) {}
    virtual void react(StopMoving const &) {}
    virtual void react(StartWorking const &) {}
    virtual void react(StopWorking const &) {}
};

// -----------------------
// 空闲状态 Idle
// -----------------------

struct Idle : RobotState
{
    void exit() override
    {
        std::cout << "退出 Idle 状态\n";
    }

    void entry() override
    {
        std::cout << "进入 Idle 状态\n";
    }

    void react(StartWorking const &) override
    {
        std::cout << "Idle -> Working\n";
        transit<Working>();
    }

    void react(StartMoving const &) override
    {
        std::cout << "Idle -> Moving\n";
        transit<Moving>(); // will first call exit and then entry function
    }
};

// -----------------------
// 移动状态 Moving
// -----------------------

struct Moving : RobotState
{
    void exit() override
    {
        std::cout << "退出 Moving 状态\n";
    }
    void entry() override
    {
        std::cout << "进入 Moving 状态\n";
    }

    void react(StopMoving const &) override
    {
        std::cout << "Moving -> Idle\n";
        transit<Idle>();
    }

    void react(StartWorking const &) override
    {
        std::cout << "Moving -> Working\n";
        transit<Working>();
    }
};

// -----------------------
// 执行任务状态 Working
// -----------------------

struct Working : RobotState
{
    void exit() override
    {
        std::cout << "退出 Working 状态\n";
    }
    void entry() override
    {
        std::cout << "进入 Working 状态\n";
    }

    void react(StopWorking const &) override
    {
        std::cout << "Working -> Idle\n";
        transit<Idle>();
    }
};

// -----------------------
// FSM 初始状态设置
// -----------------------

FSM_INITIAL_STATE(RobotState, Idle)

// -----------------------
// 主函数测试
// -----------------------
/**
 * docker run -it --env="DISPLAY=192.168.0.108:0.0" --env="QT_X11_NO_MITSHM=1" -v /tmp/.X11-unix:/tmp/.X11-unix althack/ros2-humble-gazebo:v0.0.1 bash
 *
 * @return
 */
int main()
{
    // 启动 FSM
    RobotState::start(); // will call enter function internal

    // 模拟一系列事件（注意：必须通过 RobotState 派发）
    RobotState::dispatch(StartMoving{}); // dispatch will call react function internal
    // RobotState::dispatch(StartWorking{});
    // RobotState::dispatch(StopWorking{});
    // RobotState::dispatch(StartMoving{});
    // RobotState::dispatch(StopMoving{});
    // RobotState::dispatch(StartWorking{});
    // RobotState::dispatch(StopWorking{});

    return 0;
}
